Skip to content

S12-04 小程序-uni-app

[TOC]

概述

跨平台开发

邂逅跨平台开发

传统移动端开发方式

  • 自从 iOS 和 Android 系统诞生以来,移动端开发主要由 iOSAndroid 这两大平台占据。

  • 早期的移动端开发人员主要是针对 iOS 和 Android 这两个平台分别进行同步开发。

  • 原生开发模式优缺点

    • 原生 App 在体验、性能、兼容性都非常好,并可以非常方便使用硬件设备,比如:摄像头、罗盘等

    • 但是同时开发两个平台,无论是成本上,还是时间,对于企业来说这个花费都是巨大,不可接受的。

    • 纯原生 开发效率上线周期 也严重影响了应用快速的迭代,也不利于多个平台版本控制等。

image-20240731112249087

跨平台开发的诞生

  • 因为原生 App 存在:时间长、成本高、迭代慢、部署慢、不利于推广等因素。

  • 导致了跨平台开发的概念渐渐走进了人们的视野。

  • 因此 “一套代码,多端运行” 的跨平台理念也应运而生 。

跨平台 vs 原生

原生开发的特点:

  • 性能稳定,使用流畅,用户体验好、功能齐全,安全性有保证,兼容性好,可使用手机所有硬件功能

  • 但是开发周期长、维护成本高、迭代慢、部署慢、新版本必须重新下载应用

  • 不支持跨平台,必须同时开发多端代码

跨平台开发的特点:

  • 可以跨平台,一套代码搞定 iOS、Android、微信小程序、H5 应用等

  • 开发成本较低,开发周期比原生

  • 适用于跟系统交互少、页面不太复杂的场景。

  • 但是对开发者要求高,除了本身 JS 的了解,还必须熟悉一点原生开发

  • 不适合做高性能、复杂用户体验,以及定制高的应用程序。比如:抖音、微信、QQ 等。

  • 同时开发多端兼容和适配比较麻烦、调试起来不方便。

发展史

跨平台发展史

  • 2009 年以前,当时最要是使用最原始的 HTML + CSS + JS 进行移动端 App 开发。

  • 2009-2014 年间, 出现了 PhoneGap 、Cordova 等跨平台框架,以及 Ionic 轻量级的手机端 UI 库。

  • 2015 年,ReactNative(跨平台框架)掀起了国内跨平台开发热潮,一些互联网大厂纷纷投入 ReactNative 开发阵营。

  • 2016 年,阿里开源了 Weex,它是一个可以使用现代化 Web 技术开发高性能原生应用的框架。

  • 2017 年 Google I/O 大会上,Google 正式向外界公布了 Flutter,一款跨平台开发工具包,用于为 Android、iOS、Web、Windows、Mac 等平台开发应用。

  • 2017 年至今,微信小程序uni-appTaro 等一系列跨平台小程序框架陆续流行起来了。

应该如何选择?个人建议

  • 需要做高性能、复杂用户体验、定制高的 APP、需硬件支持的选 原生开发

  • 需要性能较好、体验好、跨 Android、iOS 平台、 H5 平台、也需要硬件支持的选 Flutter(采用 Dart 开发)

  • 需要跨小程序、H5 平台、Android、iOS 平台、不太复杂的先选 uni-app,其次选 Taro

  • 不需要跨平台的,选择对应技术框架即可。

image-20240731112315327

框架对比

image-20240731112328004

项目实战

image-20240731112343936

uni-app

认识uni-app

官网对 uni-app 的介绍:

  • uni-app 是一个使用 Vue.js开发前端应用的框架。

  • 即开发者编写一套代码,便可发布到 iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

  • uni-app 在手,做啥都不愁。*即使不跨端, uni-app 也是更好的小程序开发框架、更好的 App 跨平台框架、更方便的 H5 开发框架。*不管领导安排什么样的项目,你都可以快速交付,不需要转换开发思维、不需要更改开发习惯。

image-20240731151506687

uni-app 的历史

  • uni-app 中的 uni,读 you ni,是统一的意思。

  • DCloud 于 2012 年开始研发的小程序技术,并推出了 HBuilder X 开发工具。

  • 2015 年,DCloud 正式商用了自己的小程序,产品名为“流应用”,

  • 该应用能接近原生功能和性能的 App,并且即点即用,不需要安装

  • 微信团队经过分析,于 2016 年初决定上线微信小程序业务,但其没有接入中国产业联盟标准,而是订制了自己的标准。

uni-app vs 微信小程序

uni-app 和微信小程序相同点

  • 都是接近原生的体验、打开即用、不需要安装

  • 都可开发微信小程序、都有非常完善的官方文档

uni-app 和微信小程序区别

  • uni-app 支持跨平台,编写一套代码,可以发布到多个平台。

    而微信小程序不支持

  • uni-app 纯 Vue 体验、高效、统一、工程化强。

    微信小程序工程化弱、使用小程序开发语言。

  • 微信小程序适合较复杂定制性较高、兼容和稳定性更好的应用。

    uni-app 适合不太复杂的应用,因为需要兼容多端,多端一起兼容和适配增加了开发者心智负担。

uni-app 和 微信小程序,应该如何选择

  • 需要跨平台、不太复杂的应用选 uni-app,复杂的应用使用 uni-app 反而增加了难度。

  • 不需要跨平台、较复杂、对兼容和稳定性要求高的选原生微信小程序。

架构图

image-20240731153121045

环境搭建

创建uni-app项目

一、下载HBuilder X:

Hbuilder X 是通用的前端开发工具,但为 uni-app 做了特别强化 。

下载地址:https://www.dcloud.io/hbuilderx.html

*注意:*用 Vue3 的 Composition API 建议用 HBuilder X 最新 Alpha 版,旧版有兼容问题(24年已经没有该问题)

二、注册账号

安装完之后可以注册一个 Dcloud 的开发者账号,左下角可以点击注册

三、创建uni-app项目

支持 可视化界面Vue-CLI 两种方式创建uni-app项目。可视化方式比较简单,HBuilder X 内置相关环境,开箱即用。

方式一:HBuilderX 创建 uni-app 项目步骤(推荐):

  • 点工具栏里的文件 - 新建 - 项目(快捷键 Ctrl+N)

  • 选择 uni-app 类型,输入工程名,选择模板,选择 Vue 版本,点击创建即可。

image-20240731154839200

方式二: Vue-CLI 命令行创建

  • 全局安装 Vue-CLI (目前仍推荐使用 vue-cli 4.x )

    sh
    pnpm install -g @vue/cli@4
  • 创建项目

    sh
    vue create -p dcloudio/uni-preset-vue my-project-names

HBuilderX

  • Vue3支持:HBuilderX从v3.2.5(包含)开始优化了对vue3的支持。支持setup

  • 语法高亮:HBuilderX 支持各种表达式语法,如 less、scss、stylus、typescript 等高亮,无需安装插件。

  • 代码提示:

    • API帮助及提示:在代码助手右侧还能看到清晰的帮助描述
    • this的精准识别
    • 语法提示:支持参数变量提示及转到定义
    • 指令提示:支持v-bind等提示。
    • 自定义组件提示:组件的标签、属性都可以直接被提示出来。
    • doc:支持强大的vue doc,通过类jsdoc的写法,可让你的组件实现全面的代码提示和帮助。
    • 自动保存:临时文件始终会自动保。
  • 更多功能:https://hx.dcloud.net.cn/Tutorial/Language/vue

运行uni-app

一、浏览器运行:

选中 uniapp 项目,点击工具栏的运行 -> 运行到浏览器 -> 选择浏览器,即可体验 uni-app 的 web 版。

image-20240731160615925

二、微信开发者工具运行:

选中 uniapp 项目,点击工具栏的运行 -> 运行到小程序模拟器 -> 微信开发者工具,即可在微信开发者工具里面体验 uni-app。

注意:

  • 需要在微信开发者工具中开启服务端口,目的是让 HBuilder 可以启动微信开发者工具。

    微信开发者工具设置 -> 安全

    image-20240731161024055

  • 第一次使用需配置微信开发者工具的安装路径

    点击工具栏运行 -> 运行到小程序模拟器 -> 运行设置

    image-20240731112537651

  • 自动启动失败,可用微信开发者工具手动打开项目(项目在 unpackage/dist/dev/mp-weixin 路径下)。

三、手机或模拟器运行:

注意: 需要先安装模拟器。

1、先连接真机或者模拟器,Android 的还需要配置 adb 调试桥命令行工具

见:模拟器

2、选中uniapp项目,点击工具栏的运行 - 运行到手机或模拟器,即可在该设备里面体验 uni-app(支持中文路径)。

模拟器

mumu模拟器

一、下载mumu模拟器

二、安装mumu模拟器

三、配置adb调试桥命令行工具

*adb调试桥:*用于 HBuilderX 和 Android 模拟器建立连接,来实时调试和热重载。HBuilderX 是有内置 adb 的

1、adb 目录位置:

  • HBuilderX正式版:

    • windows:安装路径下的 plugins/launcher-tools/tools/adbs
    • mac:HBuilderX.app/Contents/tools/adbs
  • HBuilderX Alpha版:

    • windows:安装路径下的 plugins/launcher-tools/tools/adbs

      注意: 需先运行后安装了插槽才会有该目录

    • mac:/Applications/HBuilderX-Alpha.app/Contents/HBuilderX/plugins/launcher/tools/adbs

2、设置全局环境变量

  • 点击此电脑 - 属性 - 高级系统设置 - 高级 - 环境变量 - Path

  • 在path中添加一条新的环境变量:D:\Program Files\HBuilderX\plugins\launcher-tools\tools\adbs

3、运行adb命令,建立链接

sh
# 注意:端口7555是固定的,启动mumu模拟器默认是运行在7555端口
adb connect 127.0.0.1:7555 # 将计算机与远程 Android 设备建立连接

adb devices # 列出所有已连接到计算机的 Android 设备,并显示它们的状态

adb kill-server # 启动adb服务器进程
adb start-server # 停止adb服务器进程

四、运行到手机或模拟器

选中项目 -> 运行 ->运行到手机或模拟器-> 运行到Android App基座,运行项目到手机模拟器中

注意:基座其实是一个app壳

其它模拟器

Mac 电脑:可以安装 Xcode 或者 Android Studio 软件。推荐 XCode。

Window 电脑:

  • 安装 mumu、夜神、雷电模拟器等(推荐)

  • 可以安装 Android Studio 软件(模拟器大、速度慢、卡)。

详细安装教程

  • 可以看资料中对应的安装文档

image-20240731112556637

image-20240731112605006

目录结构

image-20240731112617710

开发规范

为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:

  • 页面文件遵循 Vue 单文件组件 (SFC) 规范

  • 组件标签靠近小程序规范,详见uni-app组件规范

  • 接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni,详见 uni-app接口规范

  • 数据绑定事件处理同 Vue.js 规范,同时补充了 App 及页面的生命周期

  • 为兼容多端运行,建议使用 flex 布局进行开发,推荐使用 rpx 单位(750 设计稿)。

  • 文档直接查看 uni-app 的官网文档: https://uniapp.dcloud.net.cn/

全局文件

入口文件

  • main.js 是 uni-app 的入口文件,主要作用是:

    • 初始化 vue 实例。

      image-20240801162246878

    • 定义全局组件。

      image-20240731112648907

    • 定义全局属性。

      image-20240731112700056

    • 安装插件,如:pinia、vuex 等。

      image-20240801162421343

全局样式

全局样式编写位置:

1、App.vue<style>标签

  • style标签不支持scoped,写了导致样式无效。

  • 通过 @import 语句可以导入外联样式,一样作用于每一个页面。

    image-20240801165603210

2、uni.scss文件

  • 通常用来定义全局变量

  • 通过 @import 语句可以导入外联样式,一样作用于每一个页面。

    image-20240731112754018

App.vue

App.vue 入口组件

  • App.vue 是 uni-app 的入口组件,所有页面都是在 App.vue 下进行切换

  • App.vue 本身不是页面,这里不能编写视图元素,也就是没有<template>元素

App.vue 的作用

  • 应用的生命周期
  • 编写全局样式
  • 定义全局数据 globalData

注意:

  • 应用生命的周期仅可在 App.vue 中监听,在页面监听无效。
  • App.vue中不支持scoped,添加则样式无效

image-20240731112737696

uni.scss

作用:

1、定义自定义的全局样式变量

在此处定义的变量,在其他页面可以直接使用,不需要使用@import重新引入。

image-20240805121204367

2、重写uni-app内置的样式变量

image-20240805120934613

3、重写uni-ui内置的样式变量

生效条件:

1、使用uni.scss中的变量,需在HBuilderX里面安装scss插件:dart-sass

2、需要在该组件的 style 上加lang="scss",重启生效。

image-20240731112816422

注意:

  • 这里的 uni-app 框架内置变量和后面 uni-ui 组件库的内置变量是不一样的。

  • uni.scss 定义的变量是全局可以直接使用;

    App.vue 定义的变量只能在当前组件中使用。

局部样式

  • pages目录下的vue文件的style中的样式为局部样式。

    只作用对应的页面,并会覆盖 App.vue 中相同的选择器。

  • style标签支持scss等预处理器。

  • style标签不支持scoped

全局数据

在App.vue中可以定义全局的数据。在pages中可以通过getApp()函数获取App实例。

  • getApp()(),用于获取当前应用实例,可用于获取定义的全局数据,兼容h5、weapp、app。
    • 返回值:
    • appApp实例,可以通过它获取定义的全局数据

image-20240731112850584

  • getCurrentPages()(),用于获取当前页面栈的实例,以数组形式按栈的顺序给出。

    • 返回值:

    • pagesarray,当前页面栈的实例数组。第一个元素为首页,最后一个元素为当前页面。

    • 注意: 仅用于展示页面栈的情况,请勿修改页面栈,以免造成页面状态错误。

常用方法如下图所示:

image-20240731112832760

image-20240805125545315

全局配置

pages.json 文件用来对 uni-app 进行全局配置,类似微信小程序中 app.json,兼容h5、weapp、app。

  • 决定页面的路径、窗口样式、原生的导航栏、底部的原生 tabbar 等。

image-20240731112858630

1、globalStyle: 设置默认页面的窗口表现

image-20240805130311336

2、pages:设置页面路径及窗口表现

image-20240805130612091

应用配置

manifest.json 应用配置

  • Android 平台相关配置

  • iOS 平台相关配置

  • Web 端相关的配置

  • 微信小程序相关配置

    • wxbc30134b589795b0
  • ....

image-20240731112912032

内置组件

常用内置组件

  • view:视图容器。类似于传统 html 中的 div,用于包裹各种元素内容。(视图容器可以使用 div 吗?可以,但 div 不跨平台)

  • text:文本组件。用于包裹文本内容。

  • button:在小程序端的主题 和 在其它端的主题色不一样(可通过条件编译来统一风格)。

  • image:图片。默认宽度 320px、高度 240px

    • 支持相对路径、绝对路径,支持导入,支持 base64 码;
  • scrollview:可滚动视图区域,用于区域滚动。

    • 使用竖向滚动时,需要给<scroll-view>一个固定高度,通过 css 设置 height

    • 使用横向滚动时,需要给<scroll-view>添加 white-space: nowrap; 样式,子元素设置为行内块级元素。

    • APP 和小程序中,请勿在 scroll-view 中使用 mapvideo 等原生组件。

    • 小程序的 scroll-view 中也不要使用 canvastextarea 原生组件。

    • 若要使用下拉刷新,建议使用页面的滚动,而不是 scroll-view 。

  • swiper:滑块视图容器,一般用于左右滑动或上下滑动比如 banner 轮播图。

    • 默认宽 100%,高为 150px,可设置 swiper 组件高度来修改默认高度,图片宽高可用 100%。

尺寸单位(rpx)

uni-app 支持的通用 css 单位包括 px、rpx(推荐单位)、vh、vw

  • px 即屏幕像素,rpx 是响应式像素( responsive pixel ),可以根据屏幕宽度进行自适应。

  • 规定屏幕宽为 750rpx。如在 iPhone6 上,屏幕宽度为 375px,共有 750 个物理像素。

    则 750rpx = 375px = 750 物理像素,1rpx = 0.5px = 1 物理像素。

  • 建议: 开发微信小程序时设计师可以用 iPhone6 作为设计稿的标准(即:设计稿宽度为 750px)。

    image-20240731112933563

样式导入

使用 @import 语句可以导入外联样式(css 或 scss)

@import 后跟需要导入的外联样式表的相对路径, 用 ; 表示语句结束。

  • 除了相对路径,默认是支持绝对路径(即 @别名前缀

    • 相对路径../../common/base.css

    • 绝对路径@/static/common/base.css

image-20240731113008367

背景图片

uni-app 支持使用在 css 里设置背景图片,使用方式与普通 web 项目大体相同,但需要注意以下几点:

  • 支持 base64 格式图片,支持网络路径图片。

  • 小程序不支持在 css 中使用本地图片,包括背景图字体文件,需转成 base64 后使用。如何转?

  • 使用本地背景图片或字体图标需注意:

    • 为方便开发者,在背景图片小于 40kb 时,uni-app 编译到不支持本地背景图的平台时,会自动将其转化为 base64 格式

      • 注意:要转化的小图片必须存放在static/的根目录下,不能放在它的子目录中,否则不会转化为base64格式
    • 图片大于等于 40kb,会有性能问题,不建议使用太大的背景图,如开发者必须使用,则需自己将其转换为 base64 格式使用,或将其挪到服务器上,从网络地址引用。

    • 本地背景图片引用路径推荐使用以 ~@ 开头的绝对路径。

image-20240731113020524

字体图标

uni-app 支持使用字体图标,使用方式与普通 web 项目相同,注意事项也和背景图片一样,使用步骤如下:

  • 先制作字体图标,比如:可以在 iconfont 网站中生成

  • 将字体图标文件引入项目,比如:iconfont.ttf

  • 在全局的 css 中引入字体图标,比如:App.vue

image-20240731113033335

image-20240731113038947

uni-ui

概述

什么是 uni-ui?

uni-ui 特点

  • 高性能

    • 自动差量更新数据

      uni-app 引擎底层会自动用 diff 算法更新数据。

    • 优化逻辑层和视图层通讯折损

      比如,需要跟手式操作的 UI 组件,底层使用了 wxs、bindingx 等技术,实现了高性能的交互体验

      • WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。

      • bindingx 技术提供了一种称之为表达式绑定(Expression Binding) 的机制,在 weex 上让手势等复杂交互操作以 60fps 的帧率流畅执行,而不会导致卡顿。

  • 全端

    • uni-ui 的组件都是多端自适应的,底层会抹平很多小程序平台的差异或 bug。

    • uni-ui 还支持 nvue 原生渲染、以及 PC 宽屏设备

  • 风格扩展

    • uni-ui 的默认风格是中型的,与 uni-app 基础组件风格一致。
    • 支持uni.scss,可以方便的扩展和切换应用的风格。

安装

方式一(推荐):通过 uni_modules(插件模块化规范)按需单独安装组件

  • 步骤 1:官网找到扩展组件清单,然后将所需要的组件导入到项目,导入后直接使用,无需 import 和注册。

  • 步骤 2:通常我们还想切换应用风格,这时可以在 uni.scss 导入 uni-ui 提供的内置 scss 变量,然后重启应用。

  • 注意:需要登录 DCloud 账号才能安装

方式二(推荐) :通过 uni_modules 导入全部组件

  • 如想把所有 uni-ui 组件导入到项目,可以借用 HbuilderX 插件导入。

  • 如没自动导入其他组件,可在 uni-ui 组件目录上右键选择 安装三方插件依赖 即可。

image-20240731113105195

方式三:在 HBuilderX 新建 uni-app 项目时,在模板中选择 uni-ui 模板来创建项目

  • 由于 uni-app 独特的easycom(自动导包)技术,可以免引入、注册,就直接使用符合规则的 vue 组件。

方式四:npm 安装

  • 在 vue-cli 项目中可用 npm 安装 uni-ui 库

  • 或直接在 HBuilderX 项目中用 npm 安装 。

image-20240731113116290

定制主题风格

1、安装 dart-sass 插件(一般会提示,并自动安装)

2、在uni.scss文件中引入uni-ui组件库的variable.scss变量文件,然后就可以使用或修改对应的scss变量。

变量主要定义的是主题色。

image-20240731113123553

uni-forms

一、uni-forms 组件使用步骤(类似 Element Plus 的表单组件用法):

  • 安装 uni-forms 等组件

  • uni-forms 搭建表单布局

  • 编写表单项的验证规则

  • 提交表单时验证表单项

  • 重置表单

image-20240731113138200

二、重写 uni-forms 组件样式

小程序、App 直接重写,需要添加 important

H5、App 和小程序使用::global( selector ) ,需要添加 important

H5 、App 和小程序使用::deep( selector ) ,需要添加 important

image-20240805175801293

跨端兼容

跨平台兼容

uni-app 能实现一套代码、多端运行,核心是通过编译器 + 运行时实现的:

  • 编译器:将 uni-app 统一代码编译生成每个平台支持的特有代码;如在小程序平台,编译器将.vue 文件拆分生成 wxml、wxss、js 等。

  • 运行时:动态处理数据绑定、事件代理,保证 Vue 和对应宿主平台数据的一致性;

跨平台存在的问题:

  • uni-app 已将常用的组件、JS API 封装到框架中,开发者按照 uni-app 规范开发即可保证多平台兼容,大部分业务均可直接满足。

  • 但每个平台有自己的一些特性,因此会存在一些无法跨平台的情况。

    • 大量写 if else,会造成代码执行性能低下和管理混乱。

    • 编译到不同的工程后二次修改,会让后续升级变的很麻烦。

跨平台兼容解决方案:

  • 在C语言中,通过 #ifdef#ifndef 的方式,为 windows、mac 等不同 os 编译不同的代码。

  • uni-app参考这个思路,为 uni-app 提供了条件编译手段,在一个工程里优雅的完成了平台个性化实现。

image-20240731113205847

▴条件编译

条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。

语法:#ifdef#ifndef%PLATFORM% 开头,以 #endif 结尾。

  • #ifdef:if defined,仅在某平台存在

  • #ifndef:if not defined,除了某平台均存在

  • %PLATFORM%:平台名称

image-20240731113218460

image-20240731113240971

支持条件编译的文件:

  • .vue(template 、script 、style)

  • .js 、.css 、pages.json

  • 各预编译语言文件,如:.scss、.less、.stylus、.ts、.pug

例如:设置页面的标题

  • H5 专有 API:document.title = ''

  • 微信小程序专有 API:wx.setNavigationBarTitle(object)

示例: 在template中使用条件编译

image-20240806151954584

示例: 在script中使用条件编译

image-20240806152838279

示例: 在style中使用条件编译

image-20240806153155220

注意事项

1、条件编译是利用注释实现的,在不同语法里注释写法不一样。

  • js 使用 // 注释

  • css 使用 /* 注释 */

  • vue/nvue 模板里使用 <!-- 注释 -->

image-20240731113258675

2、条件编译 APP-PLUS 包含 :APP-NVUE 和 APP-VUE。

APP-PLUS-NVUE 和 APP-NVUE 没什么区别,为了简写后面出了 APP-NVUE。

3、使用条件编译请保证编译前和编译后文件的正确性,比如 json 文件中不能有多余的逗号。

4、Android和iOS平台不支持条件编译区分,如需区分 Android、iOS 平台,请调用 uni.getSystemInfoplatform来获取平台信息。

5、微信小程序主题色是绿色,而百度支付宝小程序是蓝色,应用想分平台适配颜色,条件编译是代码量最低、最容易维护的。

新建Page页面

1、uni-app 页面是编写在 pages 目录下:

  • 可直接在 uni-app 项目上右键“新建页面”,如果勾选在pages.json中注册,HBuilderX 会自动在 pages.json 中完成页面注册

  • HBuilderX 还内置了常用的页面模板(如图文列表、商品列表等),这些模板可以大幅提升你的开发效率。

注意:

  • 每次新建页面,需在 pages.json 中配置 pages 列表手动才需配置)

  • 未在 pages.json -> pages 中配置的页面,uni-app 会在编译阶段进行忽略。

image-20240806155028217

2、删除页面:

  • 删除.vue 文件 和 pages.json 中对应的配置

3、配置tabBar

image-20240806155639162

image-20240806155812153

路由

页面路由

uni-app 有两种页面路由跳转方式:使用navigator组件跳转、调用API跳转(类似小程序,与 vue-router 不同)。

方式一:组件:navigator

image-20240806160538122

方式二:API:navigateTo、redirectTo、navigateBack、switchTab

image-20240731113339431

image-20240806160947458

▴页面间通讯

在 uni-app 中,常见页面通讯方式:

  • 方式一:url查询字符串

  • 方式二:EventChannel(可以双向通讯)

  • 方式三:事件总线

  • 方式四:全局数据globalData

  • 方式五:本地数据存储localStorage

  • 方式六:Vuex和Pinia,状态管理库

查询字符串-正向

组合式

1、传参:直接在 url 后面通过查询字符串的方式拼接。如 url 查询字符串出现特殊字符等格式,需编码

image-20240808173848282

2、接收:

  • 方式一:在onLoad生命周期中通过options.xxx获取 url 传递的参数

    image-20240808173851252

  • 方式二:在defineProps中获取url传递的参数

    image-20240808174205480

选项式

1、传参: 直接在 url 后面通过查询字符串的方式拼接。如 url 查询字符串出现特殊字符等格式,需编码

  • navigator组件

    image-20240806162307974

  • navigate API

    image-20240806162620077

2、接收: 可在 onLoad 生命周期中通过options.xxx获取 url 传递的参数

image-20240806162443156

编码: 页面跳转时传递的参数通过encodedURIComponet()函数进行编码再传输

image-20240731113428723

EventChannel

  • getOpenerEventChannel()(),用于获取跨页面通信的事件通道的方法,它通常在目标页面中使用,用于接收来自打开它的父页面(或者称之为 opener)传递过来的数据或事件。
    • 返回值
    • eventChannelEventChannel默认:,事件通道。2个页面之间可以使用 emiton 方法相互发送、监听事件。
  • eventChannel.emit()(eventName, args),触发一个事件
    • eventNamestring默认:,事件名称
    • argsany默认:,事件参数
  • eventChannel.on()(eventName, cb),持续监听一个事件
    • eventNamestring默认:,事件名称
    • cb(args => void)默认:,事件监听函数
      • args any默认:,触发事件参数
  • eventChannel.off()(eventName, cb?),取消监听一个事件。给出第二个参数时,只取消给出的监听函数,否则取消所有监听函数。
    • eventNamestring默认:,事件名称
    • cb?(args => void)默认:,事件监听函数
      • args any默认:,触发事件参数
  • eventChannel.once()(eventName, cb),监听一个事件一次,触发后失效
    • eventNamestring默认:,事件名称
    • cb(args => void)默认:,事件监听函数
      • args any默认:,触发事件参数

如果一个页面由另一个页面通过 wx.navigateTo 打开,这两个页面间将建立一条数据通道:

  • 被打开的页面可以通过 this.getOpenerEventChannel() 方法来获得一个 EventChannel 对象;
  • wx.navigateTosuccess 回调中也包含一个 EventChannel 对象。

这两个 EventChannel 对象间可以使用 emiton 方法相互发送、监听事件。

组合式
正向传参

1、传参:在跳转来源页面中传递参数

image-20240808174631930

2、接收:在跳转到的页面的onLoad函数中接收

image-20240808175940274

逆向传参

逆向传参:指的是在跳转目标页面中将数据逆向往回传递给来源页面

1、目标页: 传递参数

image-20240808180809702

2、来源页: 接收参数

image-20240808180825889

选项式
正向传参

1、传参: 在跳转来源页面中传递参数

image-20240806163652081

2、接收: 在跳转到的页面的onLoad函数中接收

EventChannel 对象的获取方式

  • Options 语法:this.getOpenerEventChannel()

  • Composition 语法:getCurrentInstance().proxy. getOpenerEventChannel()

image-20240806163719448

逆向传参

逆向传参:指的是在跳转目标页面中将数据逆向往回传递给来源页面

1、目标页: 传递参数

image-20240806165152604

2、来源页: 接收参数

image-20240806165313550

事件总线-逆向

  • uni.$emit()(eventName, args),触发全局的自定义事件
    • eventNamestring默认:,事件名称
    • argsany默认:,事件参数
  • uni.$on()(eventName, cb),监听全局的自定义事件。由 uni.$emit 触发。
    • eventNamestring默认:,事件名称
    • cb(args => void)默认:,事件监听函数
      • args any默认:,触发事件参数
  • uni.$off()(eventName, cb?),移除全局自定义事件监听器。如果没有提供参数,则移除所有的事件监听器;
    • eventNamestring默认:,事件名称
    • cb?(args => void)默认:,事件监听函数
      • args any默认:,触发事件参数
  • uni.$once()(eventName, cb),只监听一次全局的自定义事件。由 uni.$emit 触发
    • eventNamestring默认:,事件名称
    • cb(args => void)默认:,事件监听函数
      • args any默认:,触发事件参数

注意事项:

  • 需先监听,再触发事件,比如:你在 A 界面触发,然后跳转到 B 页面后才监听是不行的。

  • 通常 on 和 off 是同时使用,可以避免多次重复监听

  • 适合页面返回传递参数(逆向传参)、适合跨组件通讯,不适合界面跳转传递参数(正向传参)

组合式

1、在来源页点击跳转到目标页

image-20240808211832896

2、在目标页触发一个全局事件

image-20240808211434422

3、回到来源页监听目标页触发的事件

image-20240808211458847

选项式

1、在来源页点击跳转到目标页

image-20240808142803984

2、在目标页触发一个全局事件

image-20240808142954785

3、回到来源页监听目标页触发的事件

image-20240808142928450

image-20240808142932908

4、在来源页的onUnload()函数中取消监听事件

image-20240808143508532

生命周期

App生命周期

  • onLaunch()(options),用于在应用初始化时执行特定的逻辑,只会执行一次,通常用于进行全局的初始化操作。

作用:

  • 初始化全局变量或状态。
  • 进行一些全局配置,如设置网络请求的基础URL。
  • 获取并存储用户的登录状态或授权信息。
  • 进行一些启动时需要的数据预加载。

示例:

js
// App.vue
export default {
  onLaunch(options) {
    console.log('App launched with options:', options);

    // 初始化全局状态
    this.globalData = {
      userInfo: null,
      token: ''
    };

    // 获取用户信息示例
    this.getUserInfo();
  },
  // 其他生命周期函数...
  methods: {
    getUserInfo() {
      // 调用登录接口获取用户信息
      // 示例代码,具体实现需要根据实际情况调整
      uni.getUserInfo({
        success: res => {
          this.globalData.userInfo = res.userInfo;
          // 可以在这里处理其他逻辑,比如保存用户信息到本地存储
        },
        fail: err => {
          console.error('Failed to get user info:', err);
        }
      });
    }
  }
}

Page生命周期

  • onLoad()(options),监听页面加载,该钩子被调用时,响应式数据、计算属性、方法、侦听器、props、slots 已设置完成。
    • optionsobject,上个页面传递的数据。
  • onUnload ():``,监听页面卸载。
  • onReady():``,监听页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用,注意如果渲染速度快,会在页面进入动画完成前触发。
  • onShow():``,监听页面显示,页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面。
  • onHide():``,监听页面隐藏。
  • onPullDownRefresh():,监听用户下拉动作,一般用于下拉刷新。
    • 启用下拉刷新: 设置pages.json中的pages[{enablePullDownRefresh: true}]
    • 关闭下拉刷新: uni.stopPullDownRefresh()
  • onReachBottom():``,页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。

Options API

image-20240808155006690

Composition API

image-20240808154022862

组件生命周期

  • beforeCreate():``,在实例初始化之前被调用
  • created():``,在实例创建完成后被立即调用。
  • beforeMount():``,在挂载开始之前被调用。
  • mounted():``,挂载到实例上去之后调用。
    • 注意: 此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTick()
  • beforeUnmount():``,实例销毁之前调用。在这一步,实例仍然完全可用。
  • unmouted():``,Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

uni-app 组件支持的生命周期,与 Vue 组件的生命周期相同。

  • 组件中可以使用页面的生命周期吗?

    • Options API 语法:组件中不支持使用页面生命周期

    • Composition API 语法:组件中支持页面生命周期,不同端支持情况有差异。

      • 兼容: onReady在weapp会执行,但是在app和H5不会执行

Vue2和Vue3写法对比

image-20240731115752917

Options API

image-20240808155055814

Composition API

image-20240808154408871

生命周期流程图

img

常用API

网络请求

uni.request()(options),发起 HTTPS 网络请求

  • 参数: options

  • urlstring,(必填),开发者服务器接口地址

  • datastring | object | arrayBuffer,请求的参数

  • headerobject,设置请求的 header,header 中不能设置 Referer。content-type 默认为 application/json

  • timeoutnumber,超时时间,单位为毫秒。默认值为 60_000

  • methodOPTIONS | GET | HEAD | POST | PUT | DELETE | TRACE | CONNECT,(默认 GET),HTTP 请求方法

  • dataTypejson | 其他,(默认 json),返回的数据格式

  • responseTypetext | arraybuffer,(默认 text),响应的数据类型

  • enableHttp2boolean,开启 http2

  • enableQuicboolean,开启 quic

  • enableCacheboolean,开启 cache

  • enableHttpDNSboolean,是否开启 HttpDNS 服务。如开启,需要同时填入 httpDNSServiceId

  • httpDNSServiceldstring,HttpDNS 服务商 Id

  • enableChunkedboolean,开启 transfer-encoding chunked

  • forceCellularNetworkboolean,wifi 下使用移动网络发送请求

  • successfunction(res),接口调用成功的回调函数

    • 参数:res: {data, statusCode, header, cookies, errMsg}
  • failfunction(err),接口调用失败的回调函数

    • 参数:err: {errMsg, errno}
  • completefunction,接口调用结束的回调函数(调用成功、失败都会执行)

注意:

  • 合法域名:登录各个小程序管理后台,给网络相关的 API 配置合法域名(域名白名单)

    ​ 微信小程序开发工具,在开发阶段可以配置:不校验合法域名

  • 运行到手机时,资源没有出来时可以打开手机的调试模式

  • 请求的 header 中 content-type 默认为 application/json

method值兼容性

注意: method有效值必须大写,每个平台支持的method有效值不同

image-20240808160603151

封装请求类

image-20240808161401964

使用

image-20240808161409278

数据缓存

  • 同步存取数据的方法:

  • uni.setStorageSync()(key, data),将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容

    • 参数:key, data
    • keystring,本地缓存中指定的 key
    • dataany,需要存储的内容。只支持原生类型、Date、及能够通过JSON.stringify序列化的对象
  • uni.getStorageSync()(key),从本地缓存中同步获取指定 key 的内容

    • 参数:key
    • keystring,本地缓存中指定的 key
    • 返回值:any
    • anyany,key 对应的内容
  • uni.removeStorageSync()(key),从本地缓存中移除指定 key。

    • 参数:key
    • keystring,本地缓存中指定的 key
  • wx.clearStorageSync()(),清理本地数据缓存。

  • 异步存储数据的方法:

  • uni.setStorage():(object),将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容

    • 参数:object
    • keystring,本地缓存中指定的 key
    • dataany,需要存储的内容。只支持原生类型、Date、及能够通过JSON.stringify序列化的对象
    • encryptboolean,(默认:false),是否开启加密存储。只有异步的 setStorage 接口支持开启加密存储。最低版本 2.21.3
    • successfunction(res),接口调用成功的回调函数
    • failfunction(err),接口调用失败的回调函数
    • completefunction(res),接口调用结束的回调函数(调用成功、失败都会执行)
  • uni.getStorage()(object),从本地缓存中异步获取指定 key 的内容

    • 参数:object
    • keystring,本地缓存中指定的 key
    • encryptboolean,(默认:false),是否开启加密存储。只有异步的 setStorage 接口支持开启加密存储。最低版本 2.21.3
    • successfunction(res),接口调用成功的回调函数
    • failfunction(err),接口调用失败的回调函数
    • completefunction(res),接口调用结束的回调函数(调用成功、失败都会执行)
  • uni.removeStorage():(object),从本地缓存中移除指定 key。

    • 参数:object
    • keystring,本地缓存中指定的 key
    • successfunction(res),接口调用成功的回调函数
    • failfunction(err),接口调用失败的回调函数
    • completefunction(res),接口调用结束的回调函数(调用成功、失败都会执行)
  • uni.clearStorage()(object),清理本地数据缓存。

    • 参数:object
    • successfunction(res),接口调用成功的回调函数
    • failfunction(err),接口调用失败的回调函数
    • completefunction(res),接口调用结束的回调函数(调用成功、失败都会执行)

示例:

setStorage

image-20240808163343762

getStorage

image-20240808163459771

自定义组件

组件

uni-app组件和Vue标准组件基本相同,但是也有一点区别

easycom组件规范:

传统vue组件,需要创建组件、引用、注册,三个步骤后才能使用组件, easycom组件模式可以将其精简为一步

  • 组件安装在componentsuni_modules目录下。

  • 组件需符合 components/组件名称/组件名称.vue目录结构

    image-20240731115732802

  • 符合以上目录结构的就可不用引用、注册,直接在页面中使用该组件了。

Composition API

image-20240808172031507

使用

image-20240808172039778

Options API

image-20240808165356341

使用

image-20240808165406111

image-20240808165411535

Vue3 Options API

image-20240731115806503

Vue3 Composition API

image-20240731115815588

Pinia

认识 Pinia

  • Pinia(发音为 /piːnjʌ/,如英语中的 peenya) 是Vue的存储库,它允许跨组件、页面共享状态

  • uni-app 内置了 Pinia,使用 HBuilderX 不需要手动安装,直接使用即可。

  • 使用 CLI 需要手动安装Pinia,执行 yarn add pinianpm install pinia

Pinia 的初体验,步骤如下:

1、在 main.js 中安装 Pinia 插件

image-20240808212759781

2、创建一个 store

image-20240808212819576

3、在组件中使用

image-20240808214649486